//购物车
class Cart {
  // 防抖延时器的返回值
  times = "";
  constructor() {
    //判断是否登录的方法
    this.isLogin();
    //购物车列表渲染的方法
    this.getGoods();
    //绑定事件的方法
    this.bindEve();
  }
  //绑定事件的方法
  bindEve() {
    // console.log(this);
    //全选按钮点击事件
    this.$(".cart-main input").addEventListener("click", this.SelectAllClick);
    //事件委托,给商品列表父级元素绑定事件
    this.$(".cart-list").addEventListener("click", this.delegate);
    //绑定选中删除按钮
    this.$(".cart-main .delete").addEventListener("click", this.deleteSelected);
  }
  // 判断是否登录
  isLogin() {
    //判断是否登录;
    let id = localStorage.getItem("user_id");
    // console.log(id);
    if (!id) location.assign("./login.html?ReturnUrl=./cart.html");
  }
  //获取购物车列表数据
  async getGoods() {
    //发送ajax请求,请求地址/cart/list,请求方式get,携带参数id
    let id = localStorage.getItem("user_id");
    let token = localStorage.getItem("token");
    // console.log(id);
    //设置请求头内authorization字段
    axios.defaults.headers.common["authorization"] = token;
    let { data, status } = await axios.get(
      "http://localhost:8888/cart/list?id=" + id
    );
    // console.log(data.cart, status);
    // console.log(data.code);
    //判断登录是否过期
    if (status == 200 && data.code == 401) {
      location.assign("./login.html?ReturnUrl=./cart.html");
    }
    //判断是否请求成功
    if (data.code != 1 || status != 200) {
      layer.msg("购物车获取失败...");
      return;
    }
    //判断购物车是否有数据
    if (data.cart.length < 1) {
      layer.msg("购物车中没有添加商品...");
      return;
    }
    let html = "";
    data.cart.forEach((e) => {
      // console.log(e);
      html += `<ul class="goods-list yui3-g" goods-id="${
        e.goods_id
      }" cate-id="${e.goods_number}">
            <li class="yui3-u-3-8">
                <div class="good-item">
                    <div class="item-img">
                        <input type="checkbox" class="checkbox";>
                        <img src="${e.img_small_logo}">
                    </div>
                    <div class="item-msg">${e.title}</div>
                </div>
            </li>
            <li class="yui3-u-1-8">
                
            </li>
            <li class="yui3-u-1-8">
                <span class="price">${e.current_price}</span>
            </li>
            <li class="yui3-u-1-8">
                <div class="clearfix clearfix-losefocus">
                    <a href="#none" class="increment mins">-</a>
                    <input autocomplete="off" type="text" value="${
                      e.cart_number
                    }" minnum="1" class="itxt" onblur="Cart.loseFocus(this)">
                    <a href="#none" class="increment plus">+</a>
                </div>
                <div class="youhuo">有货</div>
            </li>
            <li class="yui3-u-1-8">
                <span class="sum">${(e.current_price * e.cart_number).toFixed(
                  2
                )}</span>
            </li>
            <li class="yui3-u-1-8">
                <div>
                    <a href="#none" class="deleted">删除</a>
                </div>
                <div>移到我的关注</div>
            </li>
        </ul>`;
    });
    //追加到页面中
    this.$(".cart-body div").innerHTML = html;
  }
  /******事件委托的分发****/
  delegate = (e) => {
    // console.log(e.target);
    let str = e.target;
    //判断点击的为单选input框
    if (str.classList.contains("checkbox")) this.oneGoodsInput(str);
    // console.log(this);
    //判断点击的为删除
    if (str.classList.contains("deleted")) this.clickDelete(str);
    //判断点击的为+号
    if (str.classList.contains("plus")) this.incrementNum(str);
    //判断点击的为-号
    if (str.classList.contains("mins")) this.decrementNum(str);
    //判断点击的为数量input
    // if (str.classList.contains('itxt')) this.loseFocus(str);
  };
  /******商品数量框失去焦点事件*********/
  static loseFocus(e) {
    // console.log(e);
    let tar = e.value.trim();
    // console.log(tar);
    //获取所需参数
    let token = localStorage.getItem("token");
    let userId = localStorage.getItem("user_id") - 0;
    let ul = e.parentNode.parentNode.parentNode;
    let id = ul.getAttribute("goods-id");
    let remaining = ul.getAttribute("cate-id") - 0;
    // console.log(remaining);
    // console.log(id);
    //正则判断输入数量是否合规
    if (!tar) {
      layer.msg("请输入需要购买的数量...");
      e.value = 1;
      return;
    }
    if (tar < 1) {
      layer.msg("请输入大于0的商品数...");
      e.value = 1;
      return;
    }
    if (!/^\d+$/.test(tar)) {
      // 校验只能为数字
      layer.msg("请输入购买的商品数量...");
      e.value = 1;
      return;
    }
    if (tar > remaining) {
      layer.msg("购买数超过库存...");
      e.value = remaining;
    }
    //计算小计
    let price = ul.querySelector(".price").innerHTML - 0;
    let itxt = ul.querySelector(".itxt").value - 0;
    // console.log(price, itxt);
    let subtotal = ul.querySelector(".sum");
    subtotal.innerHTML = (price * itxt).toFixed(2);
    //计算总价和总数
    //获取所有父级ul
    let sta = document.querySelectorAll(".cart-item-list .goods-list");
    // console.log(sta);
    //声明两个为零变量
    let quan = 0;
    let rices = 0;
    sta.forEach((e) => {
      // console.log(e);
      e.querySelectorAll(".checkbox").forEach((ele) => {
        // console.log(e);
        let ckd = ele.checked;
        // console.log(ckd);
        //判断选中状态
        if (ckd) {
          // console.log(111);
          // console.log(this);
          let tmpquan = e.querySelector(".itxt").value - 0;
          let tmprices = e.querySelector(".sum").innerHTML - 0;
          // console.log(quan, rices);
          //设置数量和价格
          quan += tmpquan;
          rices += tmprices;
        }
        //设置输出到页面
        document.querySelector(".sumprice-top strong").innerHTML = quan;
        document.querySelector(".sumprice-top .summoney").innerHTML =
          "¥" + rices.toFixed(2);
      });
    });
    //发送ajax
    //设置请求头和编码方式
    axios.defaults.headers.common["authorization"] = token;
    axios.defaults.headers["Content-Type"] =
      "application/x-www-form-urlencoded";
    let str = `goodsId=${id}&id=${userId}&number=${tar}`;
    axios
      .post("http://localhost:8888/cart/number", str)
      .then((response) => {
        // console.log(response);
        // console.log(this);
      })
      .catch(function (error) {
        console.log(error);
      });
  }
  /******+的点击事件******/
  incrementNum(plus) {
    //获取数量的input
    let input = plus.previousElementSibling;
    // console.log(input);
    //获取input中的数量
    let number = input.value - 0;
    number++;
    //输出到页面中
    input.value = number;
    //修改小计的值
    let ul = this.deep(plus);
    let remaining = ul.getAttribute("cate-id") - 0;
    // console.log(remaining);
    if (number > remaining) {
      layer.msg("购买数超过库存...");
      input.value = remaining;
    }
    this.subtotal(ul);
    //调取计算总价函数
    this.statQuanRices();
    //使用防抖发送ajax请求(全局声明一个延时器返回值)
    clearTimeout(this.times);
    this.times = setTimeout(() => {
      //获取所需参数
      let token = localStorage.getItem("token");
      let userId = localStorage.getItem("user_id") - 0;
      let goodsId = ul.getAttribute("goods-id");
      //设置请求头和编码方式
      axios.defaults.headers.common["authorization"] = token;
      axios.defaults.headers["Content-Type"] =
        "application/x-www-form-urlencoded";
      let str = `goodsId=${goodsId}&id=${userId}&number=${number}`;
      axios
        .post("http://localhost:8888/cart/number", str)
        .then((response) => {
          // console.log(response);
        })
        .catch((error) => {
          console.log(error);
        });
    }, 500);
  }
  /******-的点击事件********/
  decrementNum(mins) {
    let input = mins.nextElementSibling;
    // console.log(input);
    //获取input中的数量
    let number = input.value - 0;
    number--;
    //判断数量为零时,调用删除方法
    if (number < 1) {
      // this.clickDelete(mins);
      layer.msg("不能再减少商品数量了...");
      number = 1;
    }
    //输出到页面中
    input.value = number;
    //修改小计的值
    let ul = this.deep(mins);
    this.subtotal(ul);
    //调取计算总价函数
    this.statQuanRices();
    //使用防抖发送ajax请求(全局声明一个延时器返回值)
    clearTimeout(this.times);
    this.times = setTimeout(() => {
      //获取所需参数
      let token = localStorage.getItem("token");
      let userId = localStorage.getItem("user_id") - 0;
      let goodsId = ul.getAttribute("goods-id");
      //设置请求头和编码方式
      axios.defaults.headers.common["authorization"] = token;
      axios.defaults.headers["Content-Type"] =
        "application/x-www-form-urlencoded";
      let str = `goodsId=${goodsId}&id=${userId}&number=${number}`;
      axios
        .post("http://localhost:8888/cart/number", str)
        .then((response) => {
          // console.log(response);
        })
        .catch((error) => {
          console.log(error);
        });
    }, 500);
  }
  /******小计的计算输出*****/
  subtotal(ul) {
    //获取单价和数量
    let price = ul.querySelector(".price").innerHTML - 0;
    let itxt = ul.querySelector(".itxt").value - 0;
    // console.log(price, itxt);
    let subtotal = ul.querySelector(".sum");
    subtotal.innerHTML = (price * itxt).toFixed(2);
  }
  /******全选和反选********/
  //全选点击事件
  SelectAllClick = (e) => {
    //获取全选框状态
    // console.log(this);
    // console.log(e);
    let status = e.target.checked;
    // console.log(status);
    //单个商品单选框点击事件
    this.oneGoodsStatus(status);
    //调用统计数量价格方法
    this.statQuanRices();
  };
  //设置单个商品选中框状态
  oneGoodsStatus(s) {
    let checkbox = this.$(".item-img input");
    // console.log(checkbox);
    checkbox.forEach((e) => {
      // console.log(e);
      e.checked = s;
    });
  }
  //单个input框点击事件
  oneGoodsInput(str) {
    // console.log(str);
    //获取当前input状态
    let sta = str.checked;
    //获取所有商品复选框
    let input = this.$(".checkbox");
    //将伪数组转化为真数组
    input = [...input];
    // console.log(input);
    //判断当前所有商品复选框状态
    if (sta) {
      //some
      let res = input.some((e) => !e.checked);
      if (!res) {
        //设置全选选中
        this.$(".cart-th input").checked = true;
      }
    } else {
      //一个复选框为false就取消全选框选定
      this.$(".cart-th input").checked = false;
    }
    let ul = this.deep(str);
    this.subtotal(ul);
    this.statQuanRices();
  }
  /****统计数量和价格****/
  statQuanRices() {
    //声明数量和价格
    let quan = 0;
    let rices = 0;
    //获取商品父级ul
    this.$(".goods-list").forEach((e) => {
      // console.log(e);
      //判断当前商品是否选中
      let sta = e.querySelector(".checkbox").checked;
      // console.log(sta);
      //判断选中的商品
      if (sta) {
        let tmpquan = e.querySelector(".itxt").value - 0;
        let tmprices = e.querySelector(".sum").innerHTML - 0;
        // console.log(quan, rices);
        //设置数量和价格
        quan += tmpquan;
        rices += tmprices;
      }
      //设置输出到页面
      this.$(".sumprice-top strong").innerHTML = quan;
      this.$(".sumprice-top .summoney").innerHTML = "¥" + rices.toFixed(2);
    });
  }
  /******删除的实现*********/
  clickDelete(deleted) {
    // console.log(1111);
    layer.confirm(
      "确定删除商品?",
      {
        btn: ["确定", "取消"], //可以无限个按钮
      },
      (index, layero) => {
        //获取ul
        let ulobj = this.deep(deleted);
        // console.log(ulobj);
        //获取ajax所需数据(登录用户id,要删除的商品 id)
        let id = ulobj.getAttribute("goods-id");
        let token = localStorage.getItem("token");
        let userId = localStorage.getItem("user_id");
        //配置请求头
        axios.defaults.headers.common["authorization"] = token;
        // console.log(id, token, userId);
        // 发送ajax请求
        axios
          .get(
            "http://localhost:8888/cart/remove?id=" + userId + "&goodsId=" + id
          )
          .then(({ data, status }) => {
            // console.log(data, status);
            //判断是否请求成功
            if (status == 200 && data.code == 1) {
              //请求成功关闭弹出框
              layer.close(index); //如果设定了yes回调，需进行手工关闭
              //删除ul
              ulobj.remove();
              layer.msg("删除成功");
              //计算数量和价格
              this.statQuanRices();
            }
          })
          .catch(function (error) {
            // console.log(error);
          });
      }
    );
  }
  /******选中删除方法*********/
  deleteSelected = () => {
    // console.log(1111);
    let checkbox = this.$(".item-img input");
    // console.log(checkbox);
    checkbox.forEach((e) => {
      // console.log(e);
      let a = e.checked;
      // console.log(a);
      if (a) {
        // console.log(e);
        this.clickDelete(e);
      }
    });
  };
  /***递归获取ul父级元素****/
  deep(tar) {
    if (tar.nodeName.toLowerCase() == "ul") {
      return tar;
    }
    return this.deep(tar.parentNode);
  }
  //获取节点的方法
  $(ele) {
    let res = document.querySelectorAll(ele);
    return res.length == 1 ? res[0] : res;
  }
}
new Cart();
